﻿using com.iot.core.data;
using com.iot.core.data.entity;
using com.iot.core.exception;
using com.iot.core.infrastructure;
using com.iot.core.manager.id;
using com.iot.core.util;
using System.Net;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace com.iot.core.boot
{
    public class IotFirstMiddleware
    {
        private readonly RequestDelegate _next;
        ILogger<IotFirstMiddleware> log;
        public IotFirstMiddleware(RequestDelegate next, ILogger<IotFirstMiddleware> logger)
        {

            _next = next;
            log = logger;
        }
        void AddHeaders(HttpContext context)
        {
            context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            context.Response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
            context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
        }

        public async Task Invoke(HttpContext context, MyContext myContext)
        {
            try
            {

                AddHeaders(context);
                if (context.Request.Method.ToUpper() == "OPTIONS")
                {
                    context.Response.StatusCode = 200;
                    return;
                }
                await _next.Invoke(context);
                if (context.Response.StatusCode != (int)HttpStatusCode.OK)
                {
                    var c = (HttpStatusCode)context.Response.StatusCode;
                    var r = MyApiResult.Other((int)c, c.ToString(), "");
                    context.Response.Clear();
                    AddHeaders(context);
                    await context.Response.WriteAsJsonAsync(r);
                }

            }
            catch (Exception ex)
            {
                if (ex is MyException myex)
                {
                    var r = MyApiResult.Other(myex.code, myex.msg, "");
                    context.Response.Clear();
                    AddHeaders(context);
                    await context.Response.WriteAsJsonAsync(r);
                }
                else
                {
                    var r = MyApiResult.Other((int)(ExceptionEnum.Unkonw), "未知异常", MyExceptionUtil.GetExMsg(ex));
                    context.Response.Clear();
                    AddHeaders(context);
                    AddDB(  context, ex);
                    await context.Response.WriteAsJsonAsync(r);
                }
            }

        }
        void AddDB(HttpContext context, Exception e)
        {
            if (e is MyException 
                 
            ){
                return;
            }

            var myContext = EngineContext.Current.Resolve<MyContext>();
            var htErrorMapper = EngineContext.Current.Resolve<IRepository<HtError>>();
            var htActionLogMapper = EngineContext.Current.Resolve<IRepository<HtActionLog>>();
            var mylog = myContext.MyLog;
            var m = new HtError();
            htActionLogMapper.EntityToDto(mylog, m);
            m.Id = HtIdManager.Current.NextLong();
            m.CrtDt = DateTime.Now;
            if (string.IsNullOrEmpty(m.Url))
            {
                m.Url = context.Request.Path.ToString();
            }

            if (myContext.Pin != null)
            {
                m.Pin = MyJSON.ToJSONString(myContext.Pin);
                if (m.Pin.Length > 2000)
                {
                    m.Pin = m.Pin.Substring(0, 2000);
                } 
            }

            if (myContext.Action != null)
            {
                m.Memo = myContext.Action.Name;                
            }

            m.ExClsname= MyExceptionUtil.GetExClsname(e);
            m.ExMsg= MyExceptionUtil.GetExMsg(e);
            m.ExFullmsg=MyExceptionUtil.GetFullmsg(e);
            htErrorMapper.DB.ChangeTracker.Clear();
            htErrorMapper.Insert(m, false);
            htErrorMapper.SaveChagnesAsync();
        }
 
    }

}